home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 1998 November / Freeware November 1998.img / dist / fw_GNUbash.idb / usr / freeware / src / bash-1.14.6 / endian.c.z / endian.c
C/C++ Source or Header  |  1998-01-21  |  4KB  |  149 lines

  1. /* endian.c -- A trick for determining the byte order of a machine. */
  2.  
  3. /* Copyright (C) 1993 Free Software Foundation, Inc.
  4.  
  5.    This file is part of GNU Bash, the Bourne Again SHell.
  6.  
  7.    Bash is free software; you can redistribute it and/or modify it under
  8.    the terms of the GNU General Public License as published by the Free
  9.    Software Foundation; either version 2, or (at your option) any later
  10.    version.
  11.  
  12.    Bash is distributed in the hope that it will be useful, but WITHOUT ANY
  13.    WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14.    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15.    for more details.
  16.  
  17.    You should have received a copy of the GNU General Public License along
  18.    with Bash; see the file COPYING.  If not, write to the Free Software
  19.    Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
  20.  
  21. #include <sys/types.h>
  22. #include <stdio.h>
  23. #include "bashansi.h"
  24.  
  25. /* The name of this program, as taken from argv[0]. */
  26. char *progname;
  27.  
  28. /* The name of the source file that this code is made from. */
  29. char source_name[256];
  30.  
  31. /* The name of the define.  Either "BIG_ENDIAN" or "LITTLE_ENDIAN". */
  32. char *endian_define;
  33.  
  34. char string[9];
  35. char nstring[9];
  36.  
  37. /* Stuff "1234" into a long, and compare it against a character string
  38.    "1234".  If the results are EQ, the machine is big endian like a 68000
  39.    or Sparc, otherwise it is little endian, like a Vax, or 386. */
  40. main (argc, argv)
  41.      int argc;
  42.      char **argv;
  43. {
  44. #if defined (__STDC__)
  45.   register size_t i;
  46. #else
  47.   register int i;
  48. #endif /* !__STDC__ */
  49.   FILE *stream = (FILE *)NULL;
  50.   char *stream_name = "stdout";
  51.   union {
  52.       unsigned long l;
  53.       char s[sizeof (long)];
  54.   } u;
  55.  
  56.   progname = argv[0];
  57.  
  58.   for (i = strlen (progname); i > 0; i--)
  59.     if (progname[i] == '/')
  60.       {
  61.     progname = progname + i + 1;
  62.     break;
  63.       }
  64.  
  65.   strcpy (source_name, progname);
  66.   for (i = strlen (source_name); i > 0; i--)
  67.     if (source_name[i] == '.')
  68.       {
  69.     source_name[i] = '\0';
  70.     break;
  71.       }
  72.  
  73.   strcat (source_name, ".c");
  74.  
  75.   if (argc == 1)
  76.     {
  77.       stream_name = "stdout";
  78.       stream = stdout;
  79.     }
  80.   else if (argc == 2)
  81.     {
  82.       stream_name = argv[1];
  83.       stream = fopen (stream_name, "w");
  84.     }
  85.   else
  86.     {
  87.       fprintf (stderr, "Usage: %s [output-file]\n", progname);
  88.       exit (1);
  89.     }
  90.  
  91.   if (!stream)
  92.     {
  93.       fprintf (stderr, "%s: %s Cannot be opened or written to.\n",
  94.            progname, stream_name);
  95.       exit (2);
  96.     }
  97.  
  98.   if (sizeof (long int) == 4)
  99.     {
  100.       u.l = 0x04030201L;
  101.       (void) strcpy (string, "4321");
  102.     }
  103.   else if (sizeof (long int) == 8)
  104.     {
  105. #if defined (__GNUC__)
  106.       unsigned long fake_out_gcc;
  107.  
  108.       fake_out_gcc = (0x08070605L << 31);
  109.       fake_out_gcc = (fake_out_gcc << 1);
  110.       u.l = fake_out_gcc | 0x04030201L;
  111. #else
  112.       u.l = (0x08070605L << 32) | 0x04030201L;
  113. #endif /* !__GNUC__ */
  114.       (void) strcpy (string, "87654321");
  115.     }
  116.   else
  117.     {
  118.       fprintf (stderr,
  119.            "%s: sizeof (long int) = %d, which isn't handled here.\n",
  120.            progname, sizeof (long int));
  121.       exit (2);
  122.     }
  123.  
  124.   for (i = 0; i < sizeof (long); i++)
  125.     nstring[i] = u.s[i] + '0';
  126.   nstring[i] = '\0';
  127.  
  128.   if (strcmp (nstring, string) == 0)
  129.     endian_define = "BIG_ENDIAN";
  130.   else
  131.     endian_define = "LITTLE_ENDIAN";
  132.  
  133.   fprintf (stream, "/* %s - Define BIG or LITTLE endian. */\n\n", stream_name);
  134.   fprintf (stream,
  135. "/* This file was automatically created by `%s'.  You shouldn't\n\
  136.    edit this file, because your changes will be overwritten.  Instead,\n\
  137.    edit the source code file `%s'. */\n\n",
  138.        progname, source_name);
  139.  
  140.   fprintf (stream, "#if !defined (%s)\n", endian_define);
  141.   fprintf (stream, "#  define %s\n", endian_define);
  142.   fprintf (stream, "#endif /* %s */\n", endian_define);
  143.  
  144.   if (stream != stdout)
  145.     fclose (stream);
  146.  
  147.   exit (0);
  148. }
  149.